import type {Ref} from 'vue'
import {ref} from 'vue'
import type {UploadProps} from 'ant-design-vue'
import {error} from '@/utils/message'

export interface CropperOptions {
    maxSize?: number
    aspectRatio?: number
    shape?: 'rect' | 'circle'
    quality?: number
    outputFormat?: 'image/jpeg' | 'image/png' | 'image/webp'
}

export interface CropperResult {
    cropperModalVisible: Ref<boolean>
    cropperImageSrc: Ref<string>
    cropperRef: Ref<any>
    previewUrl: Ref<string>
    croppedFile: Ref<File | null>
    handleFileSelect: UploadProps['beforeUpload']
    zoom: (ratio: number) => void
    rotate: (angle: number) => void
    flip: (x: boolean, y: boolean) => void
    reset: () => void
    confirm: () => Promise<void>
    cancel: () => void
    aspectRatio: number
    shape: 'rect' | 'circle'
}

export function useCropper(options: CropperOptions = {}): CropperResult {
    const {
        maxSize = 5,
        aspectRatio = 1,
        shape = 'rect',
        quality = 0.95,
        outputFormat = 'image/jpeg'
    } = options

    const cropperModalVisible = ref(false)
    const cropperImageSrc = ref('')
    const cropperRef = ref()
    const previewUrl = ref('')
    const croppedFile = ref<File | null>(null)

    const handleFileSelect: UploadProps['beforeUpload'] = (file) => {
        // 验证文件类型
        const isImage = file.type.startsWith('image/')
        if (!isImage) {
            error('只能上传图片文件！')
            return false
        }

        // 验证文件大小
        const isLtMaxSize = file.size / 1024 / 1024 < maxSize
        if (!isLtMaxSize) {
            error(`图片大小不能超过 ${maxSize}MB！`)
            return false
        }

        // 读取文件并显示裁剪器
        const reader = new FileReader()
        reader.onload = (e) => {
            cropperImageSrc.value = e.target?.result as string
            cropperModalVisible.value = true
        }
        reader.readAsDataURL(file)

        return false
    }

    const zoom = (ratio: number) => {
        cropperRef.value?.zoom(ratio)
    }

    const rotate = (angle: number) => {
        cropperRef.value?.rotate(angle)
    }

    const flip = (x: boolean, y: boolean) => {
        cropperRef.value?.flip(x, y)
    }

    const reset = () => {
        cropperRef.value?.reset()
    }

    const confirm = (): Promise<void> => {
        return new Promise((resolve, reject) => {
            const result = cropperRef.value?.getResult()
            if (!result || !result.canvas) {
                reject(new Error('裁剪失败'))
                return
            }

            result.canvas.toBlob(
                (blob: Blob | null) => {
                    if (blob) {
                        const timestamp = Date.now()
                        const extension = outputFormat.split('/')[1]
                        croppedFile.value = new File(
                            [blob],
                            `cropped_${timestamp}.${extension}`,
                            {type: outputFormat}
                        )
                        previewUrl.value = result.canvas.toDataURL(outputFormat, quality)
                        cropperModalVisible.value = false
                        resolve()
                    } else {
                        reject(new Error('生成图片失败'))
                    }
                },
                outputFormat,
                quality
            )
        })
    }

    const cancel = () => {
        cropperModalVisible.value = false
        cropperImageSrc.value = ''
    }

    return {
        cropperModalVisible,
        cropperImageSrc,
        cropperRef,
        previewUrl,
        croppedFile,
        handleFileSelect,
        zoom,
        rotate,
        flip,
        reset,
        confirm,
        cancel,
        aspectRatio,
        shape
    }
}

